﻿using System.Collections.Generic;
using LBoL.Base;
using LBoL.Base.Extensions;
using LBoL.ConfigData;
using LBoL.Core.Battle.BattleActions;
using LBoL.Core.Battle;
using LBoL.Core.Cards;
using LBoL.Core.StatusEffects;
using LBoL.Core.Units;
using LBoL.Core;
using ProbeMod.Cards.Template;
using LBoLEntitySideloader.Attributes;
using LBoL.Core.Battle.Interactions;
using System.Linq;
using ProbeMod.Exhibits;
using LBoL.Presentation;
using ProbeMod.SFX.Template;
using ProbeMod.SFX;
using System;

namespace ProbeMod.Cards
{
    #region 狂热者冲锋
    public sealed class ProbeZealotChargeDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Common;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.Damage = 6;
            config.UpgradedDamage = 8;


            config.Keywords = Keyword.Replenish;
            config.UpgradedKeywords = Keyword.Replenish;

            config.RelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };
            config.UpgradedRelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };

            config.Value1 = 1;

            //config.ImageId = "";
            //config.UpgradeImageId = "";

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    [EntityLogic(typeof(ProbeZealotChargeDef))]
    public sealed class ProbeZealotCharge : ProbeCard
    {
        public override IEnumerable<BattleAction> OnDraw()
        {
            return EnterHandReactor();
        }

        public override IEnumerable<BattleAction> OnMove(CardZone srcZone, CardZone dstZone)
        {
            if (dstZone != CardZone.Hand)
            {
                return null;
            }
            return EnterHandReactor();
        }

        protected override void OnEnterBattle(BattleController battle)
        {
            if (base.Zone == CardZone.Hand)
            {
                React((LazySequencedReactor)AddToHandReactor);
            }
        }

        private IEnumerable<BattleAction> AddToHandReactor()
        {
            NotifyActivating();
            List<DamageAction> list = new List<DamageAction>();
            foreach (BattleAction action in EnterHandReactor())
            {
                yield return action;
                if (action is DamageAction item)
                {
                    list.Add(item);
                }
            }
            if (list.NotEmpty())
            {
                yield return new StatisticalTotalDamageAction(list);
            }
        }

        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            return EnterHandReactor(ensureInHand: false);
        }

        private IEnumerable<BattleAction> EnterHandReactor(bool ensureInHand = true)
        {
            AudioManager.GuardedGetInstance().FixedPlaySfx(ProbeSFXTemplate.GetSfxId<ProbeSFXZealotDef>());
            if (base.Battle.BattleShouldEnd)
            {
                yield break;
            }
            if (ensureInHand && base.Zone != CardZone.Hand)
            {
                yield break;
            }
            EnemyUnit[] array = base.Battle.EnemyGroup.Alives.SampleManyOrAll(1, base.GameRun.BattleRng);
            foreach (EnemyUnit target in array)
            {
                if (target != null && target.IsAlive)
                {
                    if (GameRun.Player.Exhibits.Any(e => e is ProbeExhibitKaldalis))
                        DeltaDamage += 4;

                    yield return AttackAction(target);
                }
            }
            yield return new ExileCardAction(this);
            yield return new DrawCardAction();
        }
    }
    #endregion

    #region 追猎者
    public sealed class ProbeStalkerDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Common;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.SingleEnemy;

            config.Cost = new ManaGroup() { Any = 1 };
            config.UpgradedCost = new ManaGroup() { Any = 1 };

            config.Damage = 8;
            config.UpgradedDamage = 12;
            config.Value1 = 4; //  2选项伤害
            config.Block = 6;
            config.UpgradedBlock = 10;

            config.Keywords = Keyword.Retain | Keyword.Exile;
            config.UpgradedKeywords = Keyword.Retain | Keyword.Exile;

            config.RelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };
            config.UpgradedRelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };

            //config.Value1 = 1;

            //config.ImageId = "";
            //config.UpgradeImageId = "";

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 追猎(衍生牌)
    /// 每蓝色：打7/10；每白色：打2防6/9 保留
    /// /// </summary>
    [EntityLogic(typeof(ProbeStalkerDef))]
    public sealed class ProbeStalker : ProbeCard
    {
        public DamageInfo Damage2
        {
            get => DamageInfo.Attack(Value1);
        }

        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            int White = SynergyAmount(consumingMana, ManaColor.White);
            int blue = SynergyAmount(consumingMana, ManaColor.Blue);
            if (White > 0 || blue > 0)
            {
                AudioManager.GuardedGetInstance().FixedPlaySfx(ProbeSFXTemplate.GetSfxId<ProbeSFXStalkerDef>());
            }
            if (White > 0)
            {
                
                for (int i = 0; i < White; i++)
                {
                    yield return AttackAction(selector, Damage2);
                    yield return DefenseAction();
                }
            }
            if (blue > 0)
            {
                for (int i = 0; i < blue; i++)
                {
                    yield return AttackAction(selector);
                }
            }
        }
    }
    #endregion

    #region 龙骑士 0 8伤8格挡
    public sealed class ProbeDragoonDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Common;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.SingleEnemy;

            config.Cost = new ManaGroup() { Any = 0 };
            config.UpgradedCost = new ManaGroup() { Any = 0 };

            config.RelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };
            config.UpgradedRelativeEffects = new List<string>() { "ProbeProtossWarriorKeywordSe" };

            config.Damage = 8;
            config.UpgradedDamage = 10;
            config.Block = 8;
            config.UpgradedBlock = 10;

            config.Keywords =  Keyword.Exile;
            config.UpgradedKeywords = Keyword.Exile;

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 龙骑士
    /// 8伤8格挡 / 10伤10格挡
    /// /// </summary>
    [EntityLogic(typeof(ProbeDragoonDef))]
    public sealed class ProbeDragoon : ProbeCard
    {
        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            yield return AttackAction(selector);
            yield return DefenseAction();
        }
    }
    #endregion

    #region 不朽者 0 10伤10护盾，对具有格挡的目标造成双倍伤害
    public sealed class ProbeImmortalDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Uncommon;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.SingleEnemy;

            config.Cost = new ManaGroup() { Any = 0 };
            config.UpgradedCost = new ManaGroup() { Any = 0 };

            config.Damage = 10;
            config.UpgradedDamage = 13;
            config.Shield = 10;
            config.UpgradedShield = 13;

            config.Keywords = Keyword.Exile;
            config.UpgradedKeywords = Keyword.Exile;

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 不朽者
    /// 10/13伤10/13护盾 ，对具有格挡/护盾目标造成双倍伤害
    /// /// </summary>
    [EntityLogic(typeof(ProbeImmortalDef))]
    public sealed class ProbeImmortal : ProbeCard
    {
        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            yield return DefenseAction();
            if(selector.GetEnemy(Battle).Block>0 || selector.GetEnemy(Battle).Shield >0)
            {
                yield return AttackAction(selector);
            }
            yield return AttackAction(selector);
        }
    }
    #endregion

    #region 巨像 Wx 对所有敌人造成5点伤害 每支付1：额外造成1次伤害。放逐区每有一张牌，此卡伤害+1  精准 保留
    public sealed class ProbeColossusDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Rare;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.AllEnemies;

            config.Cost = new ManaGroup() { White = 1 };
            config.UpgradedCost = new ManaGroup() { White = 1 };
            config.IsXCost = true;

            config.Damage = 8;
            config.UpgradedDamage = 8;

            config.Keywords = Keyword.Exile | Keyword.Accuracy | Keyword.Retain;
            config.UpgradedKeywords = Keyword.Exile | Keyword.Accuracy | Keyword.Retain;

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 巨像 Wx
    /// 对所有敌人造成8点伤害 /两次 每支付1：额外造成1次伤害。放逐区每有一张牌，此卡伤害+2  精准 保留
    /// /// </summary>
    [EntityLogic(typeof(ProbeColossusDef))]
    public sealed class ProbeColossus : ProbeCard
    {
        public int IncreasedDamage
        {
            get
            {
                if (base.Battle != null)
                {
                    return base.Battle.ExileZone.Count*2;
                }
                return 0;
            }
        }

        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            AudioManager.GuardedGetInstance().FixedPlaySfx(ProbeSFXTemplate.GetSfxId<ProbeSFXColossusDef>());
            var mana = base.PendingManaUsage.GetValueOrDefault();
            var count = SynergyAmount(mana, ManaColor.Any);
            DeltaDamage += IncreasedDamage;
            if (IsUpgraded)
                count++;
            for (int i = 0; i < count; i++)
            {
                if(Battle.BattleShouldEnd)
                    yield break;
                yield return AttackAction(selector);
            }
        }
    }
    #endregion

    #region 航母 WX 回合结束时，这张牌上每有一架拦截机，对随机目标造成8点伤害。回合开始时，如果这张牌在抽牌堆或弃牌堆，则会返回手牌。战斗结束时，若此卡没被放逐，则返还所有在这张卡上的金钱花费。每支付1：花费5金，为航母装备一架拦截机，金币不足可造不出飞机！。

    public sealed class ProbeCarrierDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Uncommon;
            config.Type = CardType.Skill;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.Nobody;

            config.Cost = new ManaGroup() { White = 1 };
            config.UpgradedCost = new ManaGroup() { White = 1 };
            config.IsXCost = true;

            config.Damage = 8;
            config.UpgradedDamage = 8;

            config.Keywords =  Keyword.Retain;
            config.UpgradedKeywords =  Keyword.Retain;

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 航母 WX 
    /// 回合结束时，这张牌上每有一架拦截机，对随机目标造成8点伤害。
    /// 回合开始时，如果这张牌在抽牌堆或弃牌堆，则会返回手牌。
    /// 战斗结束时，若此卡没被放逐，则返还所有在这张卡上的金钱花费。
    /// 每支付1：花费5金，为航母装备一架拦截机，金币不足可造不出飞机！。
    /// 初始拥有2架/升级版初始就有4架拦截机
    /// 保留
    /// /// </summary>
    [EntityLogic(typeof(ProbeCarrierDef))]
    public sealed class ProbeCarrier : ProbeCard
    {

        public int InitInterceptor => IsUpgraded ? 3 : 1;

        public int DeltaInterceptor = 0;

        public int Interceptor => InitInterceptor + DeltaInterceptor;

        public int PreGoldCost => 5;

        public int TotalGoldCost = 0;

        protected override void OnEnterBattle(BattleController battle)
        {
            ReactBattleEvent(base.Battle.Player.TurnStarting, OnPlayerTurnStarting);
            ReactBattleEvent(base.Battle.Player.TurnEnding, OnPlayerTurnEnding);
            ReactBattleEvent(base.Battle.BattleEnding, OnBattleEnding);
            TotalGoldCost = 0;
            DeltaInterceptor = 0;
        }

        private IEnumerable<BattleAction> OnBattleEnding(GameEventArgs args)
        {
            yield return new GainMoneyAction(TotalGoldCost);
        }

        private IEnumerable<BattleAction> OnPlayerTurnEnding(UnitEventArgs args)
        {
            if(Zone == CardZone.Hand)
            {
                // 回合结束释放拦截机
                for (int i = 0; i < Interceptor; i++)
                {
                    if (Battle.BattleShouldEnd)
                    {
                        yield break;
                    }
                    var enemy = Battle.RandomAliveEnemy;
                    yield return AttackAction(enemy);
                }
            }
        }

        private IEnumerable<BattleAction> OnPlayerTurnStarting(UnitEventArgs args)
        {
            // 回合开始返回手牌
            if(Zone == CardZone.Discard || Zone == CardZone.Draw)
            {
                yield return new MoveCardAction(this, CardZone.Hand);
            }
        }

        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            var mana = base.PendingManaUsage.GetValueOrDefault();
            var count = SynergyAmount(mana, ManaColor.Any);

            for(int i = 0;i<count;i++)
            {
                if(GameRun.Money > PreGoldCost)
                {
                    yield return new LoseMoneyAction(PreGoldCost);
                    TotalGoldCost += PreGoldCost;
                    DeltaInterceptor ++;
                }
                else
                {
                    
                }
            }
        }
    }

    #endregion

    #region 风暴战舰 0 造成10/15点伤害这张牌打出2/3次后放逐 填充。
    public sealed class ProbeTempestDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();
            config.IsPooled = false;
            config.FindInBattle = false;

            config.Rarity = Rarity.Uncommon;
            config.Type = CardType.Attack;
            config.Colors = new List<ManaColor>() { ManaColor.White };
            config.TargetType = TargetType.SingleEnemy;

            config.Cost = new ManaGroup() { Any = 0 };
            config.UpgradedCost = new ManaGroup() { Any = 0 };

            config.Damage = 10;
            config.UpgradedDamage = 15;

            config.Value1 = 2;  //  次数
            config.Value2 = 3;

            config.Keywords = Keyword.Replenish;

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }


    }

    /// <summary>
    /// 风暴战舰 0 造成10/15点伤害这张牌打出2/3次后放逐 填充。
    /// /// </summary>
    [EntityLogic(typeof(ProbeTempestDef))]
    public sealed class ProbeTempest : ProbeCard
    {
        public int MaxCount => IsUpgraded ? Value2 : Value1;
        public int Count = 0;
        protected override void OnEnterBattle(BattleController battle)
        {
            base.OnEnterBattle(battle);
            Count = MaxCount;
        }
        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            yield return AttackAction(selector);
            Count--;
            if(Count == 0) yield return new ExileCardAction(this);
        }
    }
    #endregion


    #region 母舰
    public sealed class ProbeMothershipDef : ProbeCardTemplate
    {
        public override CardConfig MakeConfig()
        {
            CardConfig config = GetCardDefaultConfig();

            config.Rarity = Rarity.Common;
            config.Type = CardType.Friend;
            config.TargetType = TargetType.Nobody;
            config.Colors = new List<ManaColor>() { ManaColor.Blue,ManaColor.White };
            config.IsPooled = false;

            config.Cost = new ManaGroup() { White = 3, Blue = 3 };
            config.UpgradedCost = new ManaGroup() { Any = 3, Blue = 3 };

            config.Loyalty = 4;
            config.UpgradedLoyalty = 4;

            //  被动耐久变化
            config.PassiveCost = +1;
            config.UpgradedPassiveCost = +1;

            config.ActiveCost = -3;
            config.ActiveCost = -3;

            config.ActiveCost2 = -6;
            config.UpgradedActiveCost2 = -6;

            //  大招消耗耐久.
            config.UltimateCost = -9;
            config.UpgradedUltimateCost = -9;

            config.Damage = 8;
            config.UpgradedDamage = 8;

            config.Value1 = 3;
            config.Value2 = 1;

            config.RelativeEffects = new List<string>() { "ProbeBuildingKeywordSe" };
            config.UpgradedRelativeEffects = new List<string>() { "ProbeBuildingKeywordSe" };

            config.Index = CardIndexGenerator.GetUniqueIndex(config);
            return config;
        }
    }

    /// <summary>
    /// 母舰
    /// </summary>
    [EntityLogic(typeof(ProbeMothershipDef))]
    public sealed class ProbeMothership : ProbeFriendCard
    {
        public int BossDamage
        {
            get => 200;
        }

        public int PassiveActionCount => IsUpgraded ? 2 : 1;

        protected override void OnEnterBattle(BattleController battle)
        {
            base.OnEnterBattle(battle);
            ReactBattleEvent(base.Battle.Player.TurnStarting, OnPlayerTurnStarting);
            HandleBattleEvent(Battle.CardsAddedToHand, OnAddToHand);
        }

        private void OnAddToHand(CardsEventArgs args)
        {
            if(args.Cards.Any(c=>c == this))
            {
                AudioManager.GuardedGetInstance().FixedPlaySfx(ProbeSFXTemplate.GetSfxId<ProbeSFXMothershipDef>());
            }
        }

        private IEnumerable<BattleAction> OnPlayerTurnStarting(UnitEventArgs args)
        {
            if (Zone == CardZone.Discard || Zone == CardZone.Draw)
            {
                AudioManager.GuardedGetInstance().FixedPlaySfx(ProbeSFXTemplate.GetSfxId<ProbeSFXMothershipDef>());
                yield return new MoveCardAction(this, CardZone.Hand);
            }
        }

        /// <summary>
        /// 被动：+1随机打6两次/4次
        /// </summary>
        /// <returns></returns>
        public override IEnumerable<BattleAction> GetPassiveActions()
        {
            //Triigger the effect only if the card has been summoned. 
            if (!base.Summoned || base.Battle.BattleShouldEnd)
            {
                yield break;
            }
            base.NotifyActivating();
            //Increase base loyalty.
            if (base.Loyalty > 0)
            {
                base.Loyalty += base.PassiveCost;
                for (int i = 0; i < base.Battle.FriendPassiveTimes; i++)
                {
                    if (base.Battle.BattleShouldEnd)
                    {
                        break;
                    }
                    for (int j = 0; j < PassiveActionCount; j++)
                    {
                        EnemyUnit target = base.Battle.RandomAliveEnemy;
                        yield return new DamageAction(base.Battle.Player, target, Damage,"Simple1");
                    }
                    
                }
            }
            yield break;
        }

        // 主动
        protected override IEnumerable<BattleAction> Actions(UnitSelector selector, ManaGroup consumingMana, Interaction precondition)
        {
            if (precondition == null || ((MiniSelectCardInteraction)precondition).SelectedCard.FriendToken == FriendToken.Active)
            {
                //  -4 获得3层闪避和1层光学迷彩
                base.Loyalty += base.ActiveCost;
                yield return BuffAction<Graze>(level: Value1);
                yield return BuffAction<GuangxueMicai>(duration: Value2);

                yield break;
            }else if (((MiniSelectCardInteraction)precondition).SelectedCard.FriendToken == FriendToken.Active2)
            {
                // -8 立刻结束回合,获得额外一回合。
                base.Loyalty += base.ActiveCost2;
                yield return BuffAction<ExtraTurn>(1);
                yield return new RequestEndPlayerTurnAction();
            }
            else
            {
                //  大招 召唤黑洞，把普通敌人送进二次元（？），对boss造成200点精准伤害。
                base.Loyalty += base.UltimateCost;
                base.UltimateUsed = true;

                foreach (var enemy in Battle.AllAliveEnemies)
                {
                    if (base.Battle.BattleShouldEnd)
                    {
                        break;
                    }
                    if (enemy.Config.Type == EnemyType.Boss)
                    {
                        yield return new DamageAction(base.Battle.Player, enemy, DamageInfo.Attack(BossDamage, true), "Simple1");
                        continue;
                    }
                    yield return new ForceKillAction(Battle.Player, enemy);
                }

            }

        }
    
    }
    #endregion
}
